package br.mikhas.container.application;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import br.mikhas.container.factory.AbstractScope;

/**
 * Default resource container
 * 
 * @author Mikhail Domanoski
 * 
 */
public class ApplicationScope extends AbstractScope {

	/**
	 * The name of the scope
	 */
	public static final String APPLICATION_SCOPE = "application";

	private static final Logger log = LoggerFactory
			.getLogger(ApplicationScope.class);

	private static final boolean debug = log.isDebugEnabled();

	private final Map<String, Object> resourceStore = Collections
			.synchronizedMap(new HashMap<String, Object>());

	public ApplicationScope() {
		super(APPLICATION_SCOPE);
	}

	@Override
	public Object getResource(String name) {
		name = name.intern();
		synchronized (name) {// Keep the resource manipulation safe
			if (debug)
				log.debug("Getting resource from ApplicationScope: [name="
						+ name + "]");
			return this.resourceStore.get(name);
		}

	}

	@Override
	public void removeResource(String name) {
		name = name.intern();
		synchronized (name) {
			Object resource = this.resourceStore.get(name);
			if (resource != null) {
				if (debug)
					log.debug("Removing resource from ApplicationScope: [name="
							+ name + ", resource=" + resource + "]");
				this.resourceStore.put(name, null);
				this.resourceStore.remove(resource);
			}
		}
	}

	@Override
	public void addResource(String name, Object resource) {
		name = name.intern();

		synchronized (name) {

			if (debug) {
				if (this.resourceStore.containsKey(name))
					log.debug("Overwriting resource named \"" + name
							+ "\" on application scope");
				else
					log.debug("Adding resource to ApplicationScope: [name="
							+ name + ", resource=" + resource + "]");
			}

			this.resourceStore.put(name, resource);
		}
	}
}
